package cn.ubest.mvvmcore.base

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import cn.ubest.mvvmcore.BR
import cn.ubest.mvvmcore.bean.ResultState
import cn.ubest.mvvmcore.bean.State
import cn.ubest.mvvmcore.bean.Wrapper
import cn.ubest.mvvmcore.utils.ToastUtils
import com.gyf.barlibrary.ImmersionBar
import java.lang.reflect.ParameterizedType

/**
 * Created by maoqi on 2020/9/22.
 */
abstract class BaseFragment<VM : BaseViewModel<*>, B : ViewDataBinding> : Fragment() {
    val mViewModel: VM by lazy {
        val parameterizedType = javaClass.genericSuperclass as ParameterizedType
        val cla = parameterizedType.actualTypeArguments[0] as Class<VM>
        ViewModelProvider(this).get(cla)
    }

    var mBinding: B? = null

    abstract fun initLayout(): Int
    abstract fun initData(arguments: Bundle?)
    abstract fun initView(view: View)
    abstract fun loadData()

    /**
     * databinding的VariableId，一般是绑定viewmodel，如果不使用则返回null
     */
    open fun getVariableId(): Int? {
        return BR.vm
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val rootView = inflater.inflate(initLayout(), null)
        mBinding = DataBindingUtil.bind<B>(rootView)!!
        return rootView
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mBinding?.lifecycleOwner = this
        lifecycle.addObserver(mViewModel)
        getVariableId()?.also {
            mBinding?.setVariable(it, mViewModel)
        }
        //这里监听一些通用操作，比如关闭Activity
        mViewModel.mOperatingLiveData.observe(viewLifecycleOwner, Observer {
            when (it) {
                BaseViewModel.FINISH_ACTIVITY -> activity?.finish()
            }
        })
        //这里监听loading状态的更改
        mViewModel.mLoadStatusLiveData.observe(viewLifecycleOwner, Observer {
            when (it.state) {
                State.LOADING_START -> startLoading(it.isInit)
                State.LOADING_END -> stopLoading()
                State.LOADING_FAILED -> {
                    loadFailed(it.code, it.message)
                }
            }
        })
        initStatusBar()
        initData(arguments)
        initView(view)
        loadData()
    }

    open fun initStatusBar() {
        //深色状态栏文字
        ImmersionBar.with(this).statusBarDarkFont(true).init()
    }

    open fun startLoading(isInit: Boolean) {
        (activity as BaseActivity<*, *>).startLoading(isInit)
    }

    open fun stopLoading() {
        (activity as BaseActivity<*, *>).stopLoading()
    }

    open fun loadFailed(code: Int?, message: String?) {
        message?.also {
            ToastUtils.toast(it)
        }
    }

    protected fun <T> getObserver(onSuccess: (t: T) -> Unit): Observer<ResultState<T>> {
        return Observer {
            when (it) {
                is ResultState.Start -> startLoading(it.isInit)
                is ResultState.Response -> onSuccess(it.response)
                is ResultState.Finally -> stopLoading()
                is ResultState.Error -> loadFailed(it.code, it.message)
            }
        }
    }
}